// src/components/CitySelector/index.tsx
import React, { useEffect, useState, useRef } from 'react';
import Taro from '@tarojs/taro';
import { View, Image, ScrollView } from '@tarojs/components';
import classNames from 'classnames';
import './index.less';
import {
  getCityListFun,
  getConversionFun,
} from '@/src/common/method/commonFun';
import { ensureLocationAuth } from '@/src/utils/locationAuth'; // ✅ 新增
import store from '@/src/store';

export interface City {
  areaCode: string;
  areaName: string;
  letter: string;
}
export interface Province {
  areaCode: string;
  areaName: string;
  children: City[];
}

export interface CitySelectorProps {
  /** 单选时返回 City，多选时返回 City[] flag是点击获取当前位置的标志 */
  onSelect: (city: City | City[], flag?: string) => void;
  /** 关闭弹窗 */
  onClose: () => void;
  /** 是否多选 */
  multipleSelection?: boolean;
  /** 打开时要选中并滚动到的省 code */
  initialProvinceCode?: string;
  /** 单选模式下打开时要选中并滚动到的市 code */
  initialCityCode?: string;
  /** 选择省份时返回 Province */
  onSelectProvince?: (province: Province) => void;
}

// 用于保存定位后的完整城市信息
type LocatedCity = City & {
  provinceCode: string;
  provinceName: string;
  location: { latitude: number; longitude: number };
};

const CitySelector: React.FC<CitySelectorProps> = ({
  onSelect,
  onClose,
  multipleSelection = false,
  initialProvinceCode,
  initialCityCode,
  onSelectProvince,
}) => {
  const [provinceData, setProvinceData] = useState<Province[]>([]);
  const [selectedProvince, setSelectedProvince] = useState<Province | null>(
    null
  );
  const [cityData, setCityData] = useState<City[]>([]);
  const [selectedCityCode, setSelectedCityCode] = useState<string[]>([]);
  const [selectedCities, setSelectedCities] = useState<City[]>([]);
  const [currentCity, setCurrentCity] = useState('定位中...');
  const [locateInfo, setLocateInfo] = useState<LocatedCity | null>(null); //  修改类型
  const [provinceScrollTop, setProvinceScrollTop] = useState(0);
  const [cityScrollId, setCityScrollId] = useState<string>('');

  // 只在初始化时滚动
  const isInitialProvince = useRef(true);
  const isInitialCity = useRef(true);

  // 统一的定位流程（forcePrompt 控制是否强制弹窗）
  const requestLocation = async (forcePrompt = false) => {
    setCurrentCity('定位中...');
    try {
      const ok = await ensureLocationAuth({
        forcePrompt,
        bypassBlock: forcePrompt,
      });
      if (!ok) {
        setCurrentCity('未授权');
        setLocateInfo(null);
        return;
      }
      const loc: any = await Taro.getLocation({
        type: 'gcj02',
        isHighAccuracy: true,
        highAccuracyExpireTime: 3000,
      });
      const location = `${loc.latitude},${loc.longitude}`;
      const res: any = await getConversionFun(location);
      store.commonStore.setCity(res.city.areaName);
      store.commonStore.setCityCode(res.city.areaCode);
      store.commonStore.setProvinceCode(res.province.areaCode);
      store.commonStore.setProvince(res.province.areaName);
      setCurrentCity(`${res.province.areaName}${res.city.areaName}`);
      const located: LocatedCity = {
        areaCode: res.city.areaCode,
        areaName: res.city.areaName,
        provinceCode: res.province.areaCode,
        provinceName: res.province.areaName,
        letter: '',
        location: { latitude: loc.latitude, longitude: loc.longitude },
      };
      setLocateInfo(located);
    } catch (err) {
      console.log(err, 'err-getLocation/convert');
      setCurrentCity('定位失败');
      setLocateInfo(null);
    }
  };

  // 1. 定位当前城市（默认不强制）
  useEffect(() => {
    requestLocation(false);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // 2. 拉取省份并做初始选中（含单选模式下的 initialCityCode）
  useEffect(() => {
    const cityList = (Taro.getStorageSync('cityList') as Province[]) || [];
    if (cityList.length > 0) {
      setProvinceData(cityList);
      const prov =
        (initialProvinceCode &&
          cityList.find((p) => p.areaCode === initialProvinceCode)) ||
        cityList[0];
      setSelectedProvince(prov);
      setCityData(prov.children);

      if (!multipleSelection && initialCityCode) {
        const city = prov.children.find((c) => c.areaCode === initialCityCode);
        if (city) {
          setSelectedCityCode([city.areaCode]);
          setSelectedCities([city]);
        }
        setTimeout(() => {
          setCityScrollId(`city-${initialCityCode}`);
        }, 50);
      }
    } else {
      getCityListFun()
        .then((res: Province[]) => {
          setProvinceData(res);
          const prov =
            (initialProvinceCode &&
              res.find((p) => p.areaCode === initialProvinceCode)) ||
            res[0];
          setSelectedProvince(prov);
          setCityData(prov.children);

          if (!multipleSelection && initialCityCode) {
            const city = prov.children.find(
              (c) => c.areaCode === initialCityCode
            );
            if (city) {
              setSelectedCityCode([city.areaCode]);
              setSelectedCities([city]);
            }
          }
        })
        .catch(console.error);
    }
  }, [initialProvinceCode, initialCityCode, multipleSelection]);

  // 3. 仅初始化时滚动居中选中省份
  useEffect(() => {
    if (!isInitialProvince.current) return;
    if (!selectedProvince || provinceData.length === 0) return;
    const lastCode = provinceData[provinceData.length - 1].areaCode;
    Taro.createSelectorQuery()
      .select('.province')
      .boundingClientRect()
      .select(`#prov-${selectedProvince.areaCode}`)
      .boundingClientRect()
      .select(`#prov-${lastCode}`)
      .boundingClientRect()
      .exec(([contRect, itemRect, lastRect]) => {
        if (!contRect || !itemRect || !lastRect) return;
        const relTop = itemRect.top - contRect.top;
        const desired = relTop - contRect.height / 2 + itemRect.height / 2;
        const contentH = lastRect.top - contRect.top + lastRect.height;
        const maxScroll = contentH - contRect.height;
        if (maxScroll <= 0) return;
        const scroll = Math.max(0, Math.min(desired, maxScroll));
        setProvinceScrollTop(scroll);
        isInitialProvince.current = false;
      });
  }, [provinceData, selectedProvince]);

  // 4. 省份点击
  const handleProvinceClick = (prov: Province) => {
    if (onSelectProvince) {
      onSelectProvince(prov);
    }
    setSelectedProvince(prov);
    setCityData(prov.children);
    setSelectedCityCode([]);
    setSelectedCities([]);
    // 切省时取消城市滚动
    setCityScrollId('');
  };

  // 5. 城市点击（单选 or 多选），并清除初始滚动标记
  const handleCityClick = (city: City) => {
    isInitialCity.current = false;
    // 用户手动点击，无需再次滚动
    setCityScrollId('');
    if (multipleSelection) {
      const idx = selectedCityCode.indexOf(city.areaCode);
      if (idx > -1) {
        setSelectedCityCode((codes) =>
          codes.filter((c) => c !== city.areaCode)
        );
        setSelectedCities((list) =>
          list.filter((c) => c.areaCode !== city.areaCode)
        );
      } else {
        setSelectedCityCode((codes) => [...codes, city.areaCode]);
        setSelectedCities((list) => [...list, city]);
      }
    } else {
      const data: any = {
        areaName: city.areaName,
        areaCode: city.areaCode,
        provinceName: selectedProvince?.areaName,
        provinceCode: selectedProvince?.areaCode,
      };
      console.log('city=====', data);
      onSelect(data);
      onClose();
    }
  };

  // 6. 多选模式下“确定” 仅返回城市列表，不返回省份
  const handleConfirm = () => {
    onSelect(selectedCities);
    onClose();
  };

  // 7. 顶部“使用定位城市”点击
  const handleUseLocatedClick = () => {
    if (!locateInfo) return;
    if (multipleSelection) {
      if (!selectedCityCode.includes(locateInfo.areaCode)) {
        setSelectedCityCode((codes) => [...codes, locateInfo.areaCode]);
        setSelectedCities((list) => [...list, locateInfo]);
        //重新定位定位度
      }
    } else {
      onSelect(locateInfo, 'mine');
      onClose();
    }
  };

  // 重新定位（用户主动触发 → 立即弹窗去设置，不考虑 48h）
  const handleLocateClick = () => {
    requestLocation(true); // forcePrompt = true
  };

  return (
    <View className="city-selector">
      {/* 当前定位 */}
      <View className="current-city">
        <View className="desc">当前地区：</View>
        <View className="current" onClick={handleUseLocatedClick}>
          {currentCity}
        </View>
        <Image
          src="https://file.linkcook.cn/image/wineMiniProgram/imgs/nearby/location.png"
          className="location"
          onClick={handleUseLocatedClick}
        />
        <View className="refresh" onClick={handleLocateClick}>
          重新定位
        </View>
      </View>

      {/* 省市列表 */}
      <View className="cityData-container">
        <ScrollView
          className="province"
          scrollY
          scrollWithAnimation
          scrollTop={provinceScrollTop}
        >
          {provinceData.map((p) => (
            <View
              id={`prov-${p.areaCode}`}
              key={p.areaCode}
              className={classNames('province-item', {
                'item-selected': selectedProvince?.areaCode === p.areaCode,
              })}
              onClick={() => handleProvinceClick(p)}
            >
              {p.areaName}
            </View>
          ))}
        </ScrollView>
        <ScrollView
          className="city"
          scrollY
          // 使用 cityScrollId，首次初始化时会滚动到该 id
          scrollIntoView={cityScrollId || undefined}
        >
          {cityData.map((c) => (
            <View
              id={`city-${c.areaCode}`}
              key={c.areaCode}
              className={classNames('city-item', {
                'city-item-selected': selectedCityCode.includes(c.areaCode),
              })}
              onClick={() => handleCityClick(c)}
            >
              {c.areaName}
            </View>
          ))}
        </ScrollView>
      </View>

      {/* 底部按钮：仅多选时显示 */}
      {multipleSelection && (
        <View className="selector-btn">
          <View
            className="restore"
            onClick={() => {
              setSelectedCityCode([]);
              setSelectedCities([]);
            }}
          >
            重置
          </View>
          <View
            className={classNames('sure', {
              disabled: selectedCities.length === 0,
            })}
            onClick={handleConfirm}
          >
            确定（{selectedCities.length}个）
          </View>
        </View>
      )}
    </View>
  );
};

export default CitySelector;
